﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Linq;

namespace Mimoza.Transport
{
    /// <summary>
    ///  Represent MAC address.
    /// </summary>
    public class MacAddress
    {
        byte[] _address;

        public MacAddress(byte[] b)
        {
            if (b == null)
                throw new ArgumentNullException("b");
            if (b.Length != 8)
                throw new ArgumentOutOfRangeException("b");
            _address = new byte[b.Length];
            Array.Copy(b, _address, b.Length);
        }

        public byte[] Address { get { return _address; } }

        public override string ToString()
        {
            return Address[0].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[1].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[2].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[3].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[4].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[5].ToString("X2", System.Globalization.CultureInfo.InvariantCulture);
        }
    }

    /// <summary>
    ///  Represent description of network adapter.
    /// </summary>
    public class Adapter
    {
        MacAddress m_macAddr;
        string m_strIpAddr;
        string m_adapterName;

        public Adapter(MacAddress macAddr, string strIpAddr, string adapterName)
        {
            m_macAddr = macAddr;
            m_strIpAddr = strIpAddr;
            m_adapterName = adapterName;
        }

        public MacAddress MACAddress
        {
            get { return m_macAddr; }
        }

        public string IPAddress
        {
            get { return m_strIpAddr; }
        }

        public string Name
        {
            get { return m_adapterName; }
        }
    }

    /// <summary>
    ///  Represent list of adapter's descriptions.
    /// </summary>
    public class AdaptersList
    {
        public AdaptersList(List<Adapter> adaptersList)
        {
            m_adaptersList = adaptersList;
        }

        public string[] GetNames()
        {
            return (m_adaptersList.Where(x => IsNotEmptyIpAddress(x))).
                Select(x => x.Name).ToArray();
        }

        public string[] GetMACAddresses()
        {
            return (m_adaptersList.Where(x => IsNotEmptyIpAddress(x))).
                Select(x => x.MACAddress.ToString()).ToArray();
        }

        public string GetMACAddress()
        {
            string[] macs = GetMACAddresses();
            if (macs != null && macs.Length > 0) return macs[0];
            else return "";
        }

        public string[] GetIPAddresses()
        {
            return (m_adaptersList.Where(x => IsNotEmptyIpAddress(x))).
                Select(x => x.IPAddress).ToArray();
        }

        protected bool IsNotEmptyIpAddress(Adapter adapter)
        {   
            try
            {
                IPAddress ipAddr = IPAddress.Parse(adapter.IPAddress);
                if (ipAddr != null && ipAddr != IPAddress.None && ipAddr.Address != 0) return true;
            }
            catch { }
            return false;
        }

        List<Adapter> m_adaptersList;
    }

    public class LocalInfo
    {
        /// <summary>
        ///  Returns local network host name.
        /// </summary>
        static public string HostName
        {
            get
            {
                return System.Net.Dns.GetHostName();
            }
        }

        /// <summary>
        /// Returns list of adapter's descriptions.
        /// </summary>
        public static AdaptersList GetAdapters()
        {
            return new AdaptersList(AdaptersInfo.GetAdapters());
        }

        /// <summary>
        /// Network MAC address of host. In case of more that one adapters returns first MAC.
        /// </summary>
        static public string MacAddress
        {
            get
            {   
                return GetAdapters().GetMACAddress();
            }
        }
    }
}
